<template>
	<view class="swipe-box">
		<view class="swipe-container">
			<view class="swipe-container-slot" :class="{ 'reset-animation': resetting }"
				:style="{ transform: `translateX(${translateX}rpx)` }" @touchstart="onTouchStart"
				@touchmove="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd" @click="handleItemClick">
				<slot></slot>
				<view class="delete-btn-trans" @click.stop="handleDelete">
					<text class="delete-text">删除</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		nextTick
	} from 'vue';

	const props = defineProps({
		deleteBtnWidth: {
			type: Number,
			default: 160
		}
	});

	const emits = defineEmits(['delete', 'drag-start', 'longPress', 'clickItemChange']);
	const resetting = ref(false);

	// 状态变量
	const translateX = ref(0);
	const startX = ref(0);
	const startY = ref(0);
	const startTime = ref(0);
	const isDragging = ref(false);
	const isClicking = ref(false);
	const isLongPressing = ref(false);
	const timer = ref(null);
	const currentDirection = ref(null); // 'left' 或 'right'

	// 阈值配置
	const LONG_PRESS_TIME = 500; // 长按时间阈值(ms)
	const MOVE_THRESHOLD = 10; // 滑动距离阈值(rpx)
	const CLICK_TIME_THRESHOLD = 300; // 点击时间阈值(ms)

	// 触摸事件处理
	const onTouchStart = (e) => {
		// 重置状态
		resetSwipeState();

		// 记录触摸开始位置和时间
		startX.value = e.touches[0].clientX;
		startY.value = e.touches[0].clientY;
		startTime.value = Date.now();
		isClicking.value = true;

		// 启动长按定时器
		timer.value = setTimeout(() => {
			if (isClicking.value) {
				isLongPressing.value = true;
				isClicking.value = false;
				emits('longPress');
			}
		}, LONG_PRESS_TIME);
	};

	const onTouchMove = (e) => {
		// 如果已经触发长按，不再处理滑动
		if (isLongPressing.value) return;

		// 计算移动距离
		const currentX = e.touches[0].clientX;
		const currentY = e.touches[0].clientY;
		const diffX = currentX - startX.value;
		const diffY = currentY - startY.value;

		// 判断是否达到滑动阈值
		if (Math.abs(diffX) > MOVE_THRESHOLD || Math.abs(diffY) > MOVE_THRESHOLD) {
			// 清除长按定时器
			clearTimeout(timer.value);
			timer.value = null;

			// 标记为非点击状态
			isClicking.value = false;

			// 如果是横向滑动，处理滑动逻辑
			if (Math.abs(diffX) > Math.abs(diffY)) {
				// 通知父组件当前组件正在滑动
				emits('drag-start');
				isDragging.value = true;

				// 限制滑动范围
				if (diffX > 0) {
					// 右滑，最大滑动距离为0
					currentDirection.value = 'right';
					// translateX.value = Math.min(props.deleteBtnWidth, diffX);
				} else {
					currentDirection.value = 'left';
					// 左滑，最大滑动距离为删除按钮宽度
					translateX.value = Math.max(-props.deleteBtnWidth, diffX);
				}
			}
		}
	};

	const onTouchEnd = (e) => {
		// 清除定时器
		clearTimeout(timer.value);

		// 如果是长按状态，不处理后续逻辑
		if (isLongPressing.value) {
			resetSwipeState();
			return;
		}

		// 如果是拖动状态，处理拖动结束逻辑
		if (isDragging.value) {
			const currentX = e.changedTouches[0].clientX;
			const diffX = currentX - startX.value;

			// 根据滑动方向和距离决定是否显示按钮
			if (currentDirection.value === 'right') {
				// 右滑逻辑
				if (diffX > props.deleteBtnWidth / 2) {
					// 右滑超过一半，显示左侧按钮（恢复原位）
					translateX.value = 0;
				} else {
					// 右滑不足，恢复原位
					translateX.value = 0;
				}
			} else if (currentDirection.value === 'left') {
				// 左滑逻辑
				if (diffX < -props.deleteBtnWidth / 2) {
					// 左滑超过一半，显示右侧按钮
					translateX.value = -props.deleteBtnWidth;
				} else {
					// 左滑不足，恢复原位
					translateX.value = 0;
				}
			}
		}
		// 如果是点击状态，触发点击事件
		else if (isClicking.value) {
			const currentX = e.changedTouches[0].clientX;
			const currentY = e.changedTouches[0].clientY;
			const diffX = currentX - startX.value;
			const diffY = currentY - startY.value;
			const timeDiff = Date.now() - startTime.value;

			// 判断是否是有效点击（时间短且移动小）
			if (Math.abs(diffX) < MOVE_THRESHOLD && Math.abs(diffY) < MOVE_THRESHOLD && timeDiff <
				CLICK_TIME_THRESHOLD) {
				// 触发点击事件
				emits('handleItemClick');
			}
		} else {
			// 如果不是拖动也不是点击，恢复原位
			translateX.value = 0;
		}

		// 重置状态
		resetSwipeState();
	};

	// 隐藏删除按钮
	const hideDeleteBtn = () => {
		if (translateX.value === 0) return;

		resetting.value = true; // 启用动画类

		// 设置为0，触发动画
		translateX.value = 0;

		// 动画结束后重置状态
		setTimeout(() => {
			resetting.value = false;
		}, 300); // 与CSS过渡时间一致
	};

	// 删除处理
	const handleDelete = () => {
		// 添加删除动画
		if (translateX.value === 0) return;

		resetting.value = true; // 启用动画类

		// 设置为0，触发动画
		translateX.value = 0;

		// 动画结束后触发删除事件
		setTimeout(() => {
			emits('delete');
			resetting.value = false;
		}, 300); // 与CSS过渡时间一致
	};

	// 重置滑动状态
	const resetSwipeState = () => {
		clearTimeout(timer.value);
		timer.value = null;
		isDragging.value = false;
		isClicking.value = false;
		isLongPressing.value = false;
	};

	// 处理点击事件 - 新增逻辑
	const handleItemClick = () => {
		// 判断删除按钮是否隐藏（translateX为0时隐藏）
		if (translateX.value === 0) {
			// 触发点击事件
			emits('clickItemChange');
		}
		// 如果删除按钮显示（translateX不为0），不做任何处理
	};

	// 暴露方法给父组件
	defineExpose({
		hideDeleteBtn
	});
</script>

<style scoped>
	.swipe-box {
		width: 100vw;
	}

	.swipe-container {
		width: auto;
		height: 150rpx;
		margin: 10rpx 45rpx;
		background: #fff;
		overflow: hidden;
		position: relative;
		transition: transform 0.3s ease;
		border-radius: 20rpx;
	}

	.swipe-container-slot {
		height: 100%;
		padding-left: 20rpx;
	}

	.delete-btn-trans {
		position: absolute;
		right: 0;
		top: 0;
		height: 100%;
		width: 160rpx;
		background-color: #ff4d4f;
		display: flex;
		align-items: center;
		justify-content: center;
		transform: translateX(100%);
		border-radius: 8rpx;
	}

	.delete-text {
		color: white;
		font-size: 32rpx;
	}

	.reset-animation {
		transition: transform 0.3s ease;
	}
</style>